2-5 M 仵

若要一次執行大量的 MATLAB 指令,可將這些指令存放於一個副檔名為 m 的檔案,並在 MATLAB 指令提示號下鍵入此檔案的主檔名即可。此種包含 MATLAB 指令的檔案都以 m 為副檔名,因此通稱 M 檔案(M-files)。例如一個名為 myTest.m 的 M 檔案,包含一連串的 MATLAB 指令,那麼只要直接鍵入 myTest,即可執行其所包含的指令:

>> pwd % 顯示目前的工作目錄(pwd = present working directory) ans = C:\Users\RogerJang\Documents\MATLAB

接著我們要用 cd 指令來進入我們的範例檔案 myTest.m 所在的目錄:

>> cd d:\matlabBook\MATLAB程式設計:入門篇\02-初探MATLAB

(如果此目錄路徑包含空格,我們就必須使用英文的單引號來包夾此目錄路徑。)

Hint
如何取得本書的範例程式:在進行上述範例時,你必須先從本書所附的範例光碟片中,將所有的範例程式拷貝到「d:matlabBookMATLAB 程式設計:入門篇」,詳見光碟內的說明。你也可以由本書作者的網頁(http://mirlab.org/jang)連到本書的網頁,就可以下載相關的範例程式碼。

接著我們可以顯示 myTest.m 的內容,如下:

>> type myTest.m % 顯示 myTest.m 的內容 % myTest: my first test M-file. % Roger Jang, March 3, 1997 fprintf('Start of myTest.m!\n'); for i = 1:3 fprintf('i = %d ---> i^3 = %d\n', i, i^3); end fprintf('End of myTest.m!\n');

接著我們就可以執行 myTest.m:

>> myTest % 執行 myTest.m Start of myTest.m! i = 1 ---> i^3 = 1 i = 2 ---> i^3 = 8 i = 3 ---> i^3 = 27 End of myTest.m!

Hint
第一註解行(H1 Help Line):myTest.m 的前兩行是註解,可以使程式易於瞭解與管理。特別要說明的是,第一註解行通常用來簡短說明此 M 檔案的功能,以便 lookfor 能以關鍵字比對的方式來找出此 M 檔案。舉例來說,myTest.m 的第一註解行包含 myTest 這個字,因此如果鍵入 lookfor myTest,MATLAB 即可列出所有在第一註解行包含 myTest 的 M 檔案,因而myTest.m 也會被列名在內。

嚴格來說,M 檔案可再細分為底稿 (Scripts) 及函數(Functions)。基本上,底稿(例如前述 myTest.m 檔)的效用和將個別 MATLAB 的指令或運算式,在 MATLAB 的命令視窗內逐一輸入完全一樣,因此在底稿執行時,可以直接使用儲存於工作空間的變數,而且在底稿中設定的變數,也都在工作空間中看得到。至於函數則需要用到輸入引數(Input Arguments)和輸出引數(Output Arguments)來傳遞資訊,這就像是 C 語言的函數,或是 FORTRAN 語言的副程序(Subroutines)。舉例來說,若要計算一個正整數的階乘(Factorial),我們可以寫一個如下的 MATLAB 函數並將之存檔於 fact01.m:

>> type fact01.m function output = fact01(n) % FACT01 Calculate factorial of a given positive integer (for-loop version) output = 1; for i = 1:n, output = output*i; end

其中 fact01 是函數名稱,n 是輸入引數,output 是輸出引數,而 i 則是此函數用到的暫時變數。要使用此函數,直接鍵入函數名稱及適當輸入引數值即可:

>> y = fact01(5) y = 120

(當然,在執行 fact01 之前,您必需先進入 fact01.m 所在的目錄。)在執行 fact01(5) 時,MATLAB 會跳入一個下層的暫時工作空間(Temperary Workspace),將變數 n 的值設定為 5 ,然後進行各項函數檔內部的各項運算,在此階段產生的所有變數(包含輸入引數 n、暫時變數 i,以及輸出引數 output)都會儲存在此暫時工作空間中。待運算完畢後,MATLAB 會將最後輸出引數 output 的值設定給上層的變數 y,並將清除此暫時工作空間及其所含的所有變數。換句話說,在呼叫函數時,您只能經由輸入引數來控制函數的輸入,經由輸出引數來得到函數的輸出,但所有的暫時變數都會隨著函數的結束而消失,您並無法得到他們的值。

MATLAB 的函數也可以是遞迴式的(Recursive),也就是說,一個函數可以呼叫他本身。舉例來說,n! = n*(n-1)!,因此前面的階乘函數可以改成遞迴式的寫法:

>> type fact02.m function output = fact02(n) % FACT02 Calculate factorial of a given positive integer (recursive version) if n == 1, % Terminating condition output = 1; return; end output = n*fact02(n-1);

Hint
有關階乘函數:前面所用到的階乘函數只是純粹用來說明 MATLAB 的函數觀念。若實際要計算一個正整數 n 的階乘(即 n!)時,可已有下列幾種方式:
  • factorial(n)
  • prod(1:n)
  • gamma(n-1)

值得注意的是,在寫一個遞迴函數時,一定要包含結束條件(Terminating Condition),否則此函數將會一再呼叫自己,進入無窮迴圈,永遠不會停止,直到電腦的記憶體被耗盡為止。以上例而言,n==1 即滿足結束條件,此時我們直接將 output 設為 1,而不再呼叫此函數本身。(請注意,在呼叫此函數時,如果 n 不是整數,一樣會進入反覆呼叫自己的無窮迴圈中。)

有關 M 檔案的其他細節,讀者可參考本書的第十五章「M 檔案」。


MATLAB程式設計:入門篇